package com.mida.dms.knw.service.impl;

import com.alibaba.fastjson.JSONObject;

import com.mida.dms.knw.Result.BaseResult;
import com.mida.dms.knw.config.enumData.DataType;
import com.mida.dms.knw.config.enumData.FrontendReportRule;
import com.mida.dms.knw.entity.*;
import com.mida.dms.knw.entity.vo.KnwSlotPage;
import com.mida.dms.knw.entity.vo.KnwSlotVo;
import com.mida.dms.knw.entity.vo.MapperPage;
import com.mida.dms.knw.mapper.*;
import com.mida.dms.knw.service.KnwSlotService;
import com.mida.dms.knw.service.SoidService;
import com.mida.dms.knw.util.CharTransFormUtil;
import com.mida.dms.knw.util.exception.DtException;
import com.mida.dms.knw.vo.KnwSlotPageVo;
import com.mida.dms.knw.vo.Page;
import com.mida.dms.knw.vo.PageResultVo;
import com.mida.dms.knw.vo.PullDownMenuVO;
import com.mida.tool.common.result.ActionResult;
import com.mida.tool.common.result.ListResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.StopWatch;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

@Service
@Slf4j
public class KnwSlotServiceImpl extends BaseResult implements KnwSlotService {
    /**
     * 本体启用状态
     */
    private static final Long ON_STATUS = 145L;
    /**
     * 启用状态
     */
    private static final Long STATUS_ON = 149L;
    /**
     * 停用状态
     */
    private static final Long STATUS_OFF = 150L;
    /**
     * 版本自增数
     */
    private static final double VERSION_ADD = 1.0;

    @Autowired
    private KnwSlotMapper knwSlotMapper;

    @Autowired
    private KnwNoumenonMapper knwNoumenonMapper;

    @Autowired
    private KnwConceptualDomainMapper knwConceptualDomainMapper;



    @Autowired
    private KnwConceptualDetailMapper conceptualDetailMapper;

    @Autowired
    private DtHistoryVersionMapper dtHistoryVersionMapper;

    @Autowired
    private KnwNoumenonRelationMapper knwNoumenonRelationMapper;
    /**
     * ID生成器
     */
    @Autowired
    private SoidService soidService;

    /**
     * 更新slot对应编码体系(支持取消绑定编码体系)
     *
     * @param slotSoid
     * @param detailCodingSystemSoid
     * @return
     */
    @Override
    @Transactional(value = "dtdTxManager", rollbackFor = Exception.class)
    public ActionResult updateDetailCoding(Long slotSoid, Long detailCodingSystemSoid) {
        log.info("开始更新slot对应编码体系");
        StopWatch stopWatch = StopWatch.createStarted();
        ActionResult actionResult = new ActionResult();
        try {
            if (ObjectUtils.isEmpty(slotSoid)){
                buildBadRequestActionWarn(actionResult,"本体slotSoid不能为空");
                return actionResult;
            }

            KnwSlot knwSlot = knwSlotMapper.selectByPrimaryKey(slotSoid);
            KnwNoumenon knwNoumenon = knwNoumenonMapper.selectByPrimaryKey(knwSlot.getNoumenonSoid());

            if (ObjectUtils.isEmpty(knwNoumenon.getVerson())){
                buildBadRequestActionWarn(actionResult,"不支持非发布状态本体slot编码体系更新");
                return actionResult;
            }

            //更新slot对应编码体系soid
            knwSlotMapper.updateDetailCoding(slotSoid,detailCodingSystemSoid);
            //更新本体发布版本
            knwNoumenon.setVerson(knwNoumenon.getVerson() + VERSION_ADD);
            knwNoumenonMapper.updateByPrimaryKey(knwNoumenon);
            buildActionSuccess(actionResult);
        } catch (Exception e) {
            log.error("更新slot对应编码体系异常", e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            buildActionWarn(actionResult, "开始更新slot对应编码体系");
        } finally {
            stopWatch.stop();
            log.info("更新slot对应编码体系耗时:" + stopWatch.getTime() + "ms");
        }
        return actionResult;
    }

    /**
     * 发布本体
     *
     * @param noumenonSoid
     * @param list
     * @return
     */
    @Override
    @Transactional(value = "dtdTxManager", rollbackFor = Exception.class)
    public ActionResult publish(Long noumenonSoid, List<KnwSlot> list) {
        log.info("开始发布本体");
        StopWatch stopWatch = StopWatch.createStarted();
        ActionResult actionResult = new ActionResult();
        try {
            if (noumenonSoid == null) {
                throw new RuntimeException("本体soid不能为空");
            }

            KnwNoumenon knwNoumenon = knwNoumenonMapper.selectByPrimaryKey(noumenonSoid);
            if (knwNoumenon.getStatus() == 146L) {
                throw new RuntimeException("停用状态的本体不能发布");
            }

            if (knwNoumenon.getStatus() == 145L && (list == null || list.size() == 0)) {
                throw new RuntimeException("无新增slot,不能重新发布");
            }

            //本体无slot且无添加的slot
            Integer count = knwSlotMapper.countSlotByNoumenonSoid(noumenonSoid);
            if (count == 0 && list == null) {
                throw new RuntimeException("本体至少需要一个slot才能发布");
            }

            //本体非首次发布
            if (knwNoumenon.getVerson() != null) {
                //历史版本记录
                Map history = new HashMap();
                history.put("knwNoumenon", knwNoumenon);
                List<KnwSlot> knwSlots = knwSlotMapper.selectAllSlotByNoumenonSoid(noumenonSoid);
                history.put("knwSlots", knwSlots);
                List<KnwNoumenonRelation> knwNoumenonRelations = knwNoumenonRelationMapper.selectRelationForHistory(knwNoumenon.getNoumenonSoid());
                history.put("knwRelations", knwNoumenonRelations);
                //版本类型内容
                String dbModelJson = JSONObject.toJSONString(history);
                DtHistoryVersion dtHistoryVersion = new DtHistoryVersion();
//                Long historyVersionSoid = oIDGanerator.getSOID();
                Long historyVersionSoid = soidService.getSoid();
                dtHistoryVersion.setHistoryVersionSoid(historyVersionSoid);
                dtHistoryVersion.setVersion(knwNoumenon.getVerson());
                //TODO
                dtHistoryVersion.setDbModelFrom(2L);
                dtHistoryVersion.setDbModelSoid(knwNoumenon.getNoumenonSoid());
                dtHistoryVersion.setIsDelete(0L);
                dtHistoryVersion.setCreateDate(new Date());
                dtHistoryVersion.setUpdateUser(null);
                dtHistoryVersion.setDbModelJson(dbModelJson);
                dtHistoryVersionMapper.insert(dtHistoryVersion);

                //历史版本国标
                soidService.insertOid(historyVersionSoid,1);
//                String oid = oIDGanerator.getOID(1);
//                DtOid dtOid = new DtOid();
//                dtOid.setOid(oid);
//                dtOid.setSoid(historyVersionSoid);
//                dtOidMapper.insert(dtOid);
            }

            if (list != null) {
                //批量新增本体slot
                for (int i = 0; i < list.size(); i++) {
                    KnwSlot knwSlot = list.get(i);
                    if (knwSlot.getNoumenonSoid() == null) {
                        throw new RuntimeException("本体soid为空");
                    }

                    if (knwSlot.getNoumenonSoid().compareTo(noumenonSoid) != 0) {
                        throw new RuntimeException("slot关联的本体soid与传入的本体soid不一致");
                    }

                    if (StringUtils.isEmpty(knwSlot.getSlotName())) {
                        throw new RuntimeException("Slot显示名称不能为空");
                    }

                    if (ObjectUtils.isEmpty(knwSlot.getDataType())) {
                        throw new RuntimeException("值类型不能为空");
                    }

                    if(ObjectUtils.isNotEmpty(knwSlot.getReferenceUpperLimit()) && ObjectUtils.isEmpty(knwSlot.getReferenceLowerLimit())){
                        throw new RuntimeException("参考值范围不能只填一个值");
                    }

                    if(ObjectUtils.isNotEmpty(knwSlot.getReferenceLowerLimit()) && ObjectUtils.isEmpty(knwSlot.getReferenceUpperLimit())){
                        throw new RuntimeException("参考值范围不能只填一个值");
                    }

                    if(ObjectUtils.isNotEmpty(knwSlot.getReferenceUpperLimit()) && ObjectUtils.isNotEmpty(knwSlot.getReferenceUpperLimit())){
                        if (knwSlot.getReferenceUpperLimit() < knwSlot.getReferenceLowerLimit()){
                            throw new RuntimeException("参考值上限不能小于参考值下限");
                        }
                    }

//                    Long slotSoid = oIDGanerator.getSOID();
                    Long slotSoid = soidService.getSoid();
                    //查重处理
                    List<KnwSlot> result = knwSlotMapper.selectDistinctWithKnwSlot(knwSlot);
                    if (result.size() > 0) {
                        throw new RuntimeException("Slot已存在");
                    }

                    //查出最大序列值
                    Long slotOrder = knwSlotMapper.getMaxSlotOrder(knwSlot.getNoumenonSoid());
                    if (slotOrder == null) {
                        slotOrder = 1L;
                    } else {
                        slotOrder++;
                    }
                    knwSlot.setSoltOrder(slotOrder);
                    knwSlot.setSlotSoid(slotSoid);
                    knwSlot.setIsDelete(0L);
                    knwSlot.setCreateDate(new Date());
                    knwSlot.setUpdateDate(new Date());
                    knwSlot.setPyCode(CharTransFormUtil.toPinyinSimple(knwSlot.getSlotName()));
                    knwSlot.setWbCode(CharTransFormUtil.toWubi(knwSlot.getSlotName()));

                    // 添加本体slot标签
                    knwSlot.setLable(FrontendReportRule.TAG_SLOT.getCodeName());
                    if(knwSlot.getDataType().longValue() == DataType.NUMBER.getCode()){
                        knwSlot.setLable(FrontendReportRule.TAG_NU.getCodeName());
                    }
                    if (knwSlot.getDataType().longValue() == DataType.VARCHAT.getCode()){
                        knwSlot.setLable(FrontendReportRule.TAG_STR.getCodeName());
                    }
                    if(knwSlot.getDerailCodingSystemSoid() != null){
                        knwSlot.setLable(FrontendReportRule.TAG_SELE.getCodeName());
                    }
                    //1.添加slot信息
                    knwSlotMapper.insert(knwSlot);

                    //国标
                    soidService.insertOid(slotSoid,1);
//                    String slotOid = oIDGanerator.getOID(1);
//                    DtOid dtSlotOid = new DtOid();
//                    dtSlotOid.setOid(slotOid);
//                    dtSlotOid.setSoid(slotSoid);
//                    dtOidMapper.insert(dtSlotOid);
                }
            }


            //版本更新
            count = knwSlotMapper.countSlotByNoumenonSoid(noumenonSoid);
            if (count > 0) {
                if (knwNoumenon.getVerson() == null) {
                    knwNoumenon.setVerson(1.0);
                    //启用本体
                    knwNoumenon.setStatus(145L);
                    knwNoumenonMapper.updateByPrimaryKey(knwNoumenon);
                } else {
                    knwNoumenon.setVerson(knwNoumenon.getVerson() + VERSION_ADD);
                    //启用本体
                    knwNoumenon.setStatus(145L);
                    knwNoumenonMapper.updateByPrimaryKey(knwNoumenon);
                }
            } else {
                throw new RuntimeException("本体至少需要一个slot才能发布");
            }
            buildActionSuccess(actionResult);
        } catch (Exception e) {
            log.error("发布本体异常", e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            buildActionWarn(actionResult, "发布本体失败");
        } finally {
            stopWatch.stop();
            log.info("本次发布耗时:" + stopWatch.getTime() + "ms");
        }
        return actionResult;
    }

    /**
     * 添加slot
     *
     * @param knwSlotVO
     * @return
     */
    @Override
    @Transactional(value = "dtdTxManager", rollbackFor = Exception.class)
    public ActionResult add(KnwSlotVo knwSlotVO) {
        log.info("开始新增本体slot" + knwSlotVO.toString());
        StopWatch stopWatch = StopWatch.createStarted();
        ActionResult actionResult = new ActionResult();
        try {
            if (knwSlotVO.getNoumenonSoid() == null) {
                buildBadRequestActionWarn(actionResult, "本体soid为空");
                return actionResult;
            }

            KnwNoumenon knwNoumenon = knwNoumenonMapper.selectByPrimaryKey(knwSlotVO.getNoumenonSoid());
            if (knwNoumenon.getStatus() != 147L) {
                buildBadRequestActionWarn(actionResult, "本体为非草稿状态,无法新增slot");
                return actionResult;
            }

            if (StringUtils.isEmpty(knwSlotVO.getSlotName())) {
                buildBadRequestActionWarn(actionResult, "Slot显示名称不能为空");
                return actionResult;
            }

            if (ObjectUtils.isEmpty(knwSlotVO.getDataType())) {
                buildBadRequestActionWarn(actionResult, "值类型不能为空");
                return actionResult;
            }

            if(ObjectUtils.isNotEmpty(knwSlotVO.getReferenceUpperLimit()) && ObjectUtils.isEmpty(knwSlotVO.getReferenceLowerLimit())){
                buildBadRequestActionWarn(actionResult, "参考值范围不能只填一个值");
                return actionResult;
            }

            if(ObjectUtils.isNotEmpty(knwSlotVO.getReferenceLowerLimit()) && ObjectUtils.isEmpty(knwSlotVO.getReferenceUpperLimit())){
                buildBadRequestActionWarn(actionResult, "参考值范围不能只填一个值");
                return actionResult;
            }

            if(ObjectUtils.isNotEmpty(knwSlotVO.getReferenceUpperLimit()) && ObjectUtils.isNotEmpty(knwSlotVO.getReferenceUpperLimit())){
                if (knwSlotVO.getReferenceUpperLimit() < knwSlotVO.getReferenceLowerLimit()){
                    buildBadRequestActionWarn(actionResult, "参考值上限不能小于参考值下限");
                    return actionResult;
                }
            }

//            Long soid = oIDGanerator.getSOID();
            Long soid = soidService.getSoid();
            //查重处理
            List<KnwSlot> knwSlots = knwSlotMapper.selectDistinct(knwSlotVO);
            if (knwSlots.size() > 0) {
                buildBadRequestActionWarn(actionResult, "Slot已存在");
                return actionResult;
            }
            //查出最大序列值
            Long slotOrder = knwSlotMapper.getMaxSlotOrder(knwSlotVO.getNoumenonSoid());
            if (slotOrder == null) {
                slotOrder = 1L;
            } else {
                slotOrder++;
            }
            knwSlotVO.setSoltOrder(slotOrder);
            //新增业务操作
            KnwSlot knwSlot = setKnwSlot(knwSlotVO, soid);
            // 添加本体slot标签
            knwSlot.setLable(FrontendReportRule.TAG_SLOT.getCodeName());
            if(knwSlot.getDataType().longValue() == DataType.NUMBER.getCode()){
                knwSlot.setLable(FrontendReportRule.TAG_NU.getCodeName());
            }
            if (knwSlot.getDataType().longValue() == DataType.VARCHAT.getCode()){
                knwSlot.setLable(FrontendReportRule.TAG_STR.getCodeName());
            }
            if(knwSlot.getDerailCodingSystemSoid() != null){
                knwSlot.setLable(FrontendReportRule.TAG_SELE.getCodeName());
            }
            //1.添加slot信息
            knwSlotMapper.insert(knwSlot);

            //国标
            soidService.insertOid(soid,1);
//            String oid = oIDGanerator.getOID(1);
//            DtOid dtOid = new DtOid();
//            dtOid.setOid(oid);
//            dtOid.setSoid(soid);
//            dtOidMapper.insert(dtOid);
            buildActionSuccess(actionResult);
        } catch (Exception e) {
            log.error("新增本体slot发送异常", e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            buildActionWarn(actionResult, "新增本体slot失败");
        } finally {
            stopWatch.stop();
            log.info("本次新增耗时:" + stopWatch.getTime() + "ms");
        }
        return actionResult;
    }

    private KnwSlot setKnwSlot(KnwSlotVo knwSlotVO, Long soid) throws Exception {
        KnwSlot knwSlot = new KnwSlot();

        knwSlot.setSoltOrder(knwSlotVO.getSoltOrder());
        knwSlot.setSlotSoid(soid);
        knwSlot.setPyCode(CharTransFormUtil.toPinyinSimple(knwSlotVO.getSlotName()));
        knwSlot.setWbCode(CharTransFormUtil.toWubi(knwSlotVO.getSlotName()));
        knwSlot.setStatus(knwSlotVO.getStatus());
        knwSlot.setIsDelete(0L);
        knwSlot.setCreateDate(new Date());
        knwSlot.setUpdateDate(new Date());
        knwSlot.setNoumenonSoid(knwSlotVO.getNoumenonSoid());
        knwSlot.setConceptualSoid(knwSlotVO.getConceptualSoid());
        knwSlot.setSlotName(knwSlotVO.getSlotName());
        knwSlot.setDerailCodingSystemSoid(knwSlotVO.getDerailCodingSystemSoid());
//        knwSlot.setSlotDesc(knwSlotVO.getSlotDesc());
        knwSlot.setDataType(knwSlotVO.getDataType());
        knwSlot.setMaxNumber(knwSlotVO.getMaxNumber());
        knwSlot.setMinNumber(knwSlotVO.getMinNumber());
        knwSlot.setDefaultNumber(knwSlotVO.getDefaultNumber());
        knwSlot.setUnit(knwSlotVO.getUnit());
        knwSlot.setBasic(knwSlotVO.getBasic());
        knwSlot.setLable(knwSlotVO.getLable());
        knwSlot.setReferenceLowerLimit(knwSlotVO.getReferenceLowerLimit());
        knwSlot.setReferenceUpperLimit(knwSlotVO.getReferenceUpperLimit());
        knwSlot.setReferenceQualitativeMaintenance(knwSlotVO.getReferenceQualitativeMaintenance());

        return knwSlot;
    }


    /**
     * 分页查询
     *
     * @param vo
     * @return
     */
    @Override
    public ListResult<PageResultVo<KnwSlotVo>> find(KnwSlotPageVo vo) {
        log.info("开始分页查询,查询条件:" + vo.toString());
        PageResultVo pvo = new PageResultVo();
        Page page = new Page(vo.getCurrentPage(), vo.getPageSize());
        pvo.setPage(page);
        StopWatch st = StopWatch.createStarted();
        ListResult result = new ListResult();
        List<KnwSlotVo> list = null;
        try {
            KnwSlotPage npage = new KnwSlotPage(vo.getCurrentPage(), vo.getPageSize(), vo.getNoumenonSoid());
            int count = knwSlotMapper.findPageCount(npage);
            if (count != 0) {
                page.setTotalCount(count);
                list = knwSlotMapper.findPageByDetail(npage);
            } else {
                pvo.setPage(null);
            }
            pvo.setList(list);
            buildListSuccess(result, pvo);
        } catch (Exception e) {
            list = new ArrayList<KnwSlotVo>(0);
            pvo.setList(list);
            log.error("分页查询本体slot发送异常", e);
            buildListWarn(result, "分页查询本体slot失败");
        } finally {
            st.stop();
            log.info("本次分页查询耗时:" + st.getTime() + "ms");
        }
        return result;
    }

    /**
     * 根据slotSoid查询一条记录
     *
     * @param soid
     * @return
     */
    @Override
    public ListResult<KnwSlotVo> findBySoid(Long soid) {
        log.info("开始根据slotSoid查询,查询条件:" + soid);
        StopWatch st = StopWatch.createStarted();
        ListResult result = new ListResult();
        try {
            KnwSlotVo knwSlotVo = knwSlotMapper.findBySoid(soid);
            buildListSuccess(result, knwSlotVo);
        } catch (Exception e) {
            log.error("根据slotSoid查询记录异常", e);
            buildListWarn(result, "根据slotSoid查询记录失败");
        } finally {
            st.stop();
            log.info("本次查询耗时:" + st.getTime() + "ms");
        }
        return result;
    }

    /**
     * 删除
     *
     * @param vo
     * @return
     */
    @Override
    @Transactional(value = "dtdTxManager", rollbackFor = Exception.class)
    public ActionResult delete(KnwSlotVo vo) {
        log.info("开始删除一个slot" + vo.getSlotSoid());
        StopWatch stopWatch = StopWatch.createStarted();
        ActionResult actionResult = new ActionResult();
        try {
            if (ObjectUtils.isEmpty(vo.getSlotSoid())) {
                log.error("slotSoid不能为空");
                buildBadRequestActionWarn(actionResult, "slotSoid不能为空");
                return actionResult;
            }
            //查询验证状态
            KnwNoumenon knwNoumenon = knwNoumenonMapper.selectByPrimaryKey(vo.getNoumenonSoid());
            if (knwNoumenon != null) {
                if (knwNoumenon.getStatus() != null && ON_STATUS.equals(knwNoumenon.getStatus())) {
                    buildBadRequestActionWarn(actionResult, "本体启用状态下不可删除");
                    return actionResult;
                }
            }

            KnwSlot knwSlot = knwSlotMapper.selectByPrimaryKey(vo.getSlotSoid());

            //逻辑删除
            KnwSlot slot = new KnwSlot();
            slot.setSlotSoid(vo.getSlotSoid());
            slot.setIsDelete(1L);
            slot.setStatus(STATUS_OFF);
            slot.setUpdateDate(new Date());
            knwSlotMapper.updateIsDeleteBySlotSoid(slot);

            //大于该slot的solt_no都减1(调整本体slot顺序)
            knwSlotMapper.adjustSlotOrder(knwSlot.getNoumenonSoid(), knwSlot.getSoltOrder());

            buildActionSuccess(actionResult);
        } catch (Exception e) {
            log.error("删除slot发送异常", e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            buildActionWarn(actionResult, "删除slot失败");
        } finally {
            stopWatch.stop();
            log.info("本次删除耗时:" + stopWatch.getTime() + "ms");
        }
        return actionResult;
    }

    /**
     * 拖拽排序
     *
     * @param originalSlotOrder
     * @param newSlotOrder
     * @param slotSoid
     * @return
     * @throws DtException
     */
    @Override
    @Transactional(value = "dtdTxManager", rollbackFor = Exception.class)
    public ActionResult order(Long originalSlotOrder, Long newSlotOrder, Long slotSoid) throws DtException {
        log.info("开始执行排序,排序的slotSoid:{},原位置:{},新位置:{}", slotSoid, originalSlotOrder, newSlotOrder);
        StopWatch stopWatch = StopWatch.createStarted();
        ActionResult actionResult = new ActionResult();

        if (ObjectUtils.isEmpty(slotSoid)) {
            log.error("slotSoid不能为空");
            buildBadRequestActionWarn(actionResult, "slotSoid不能为空");
            return actionResult;
        }
        if (ObjectUtils.isEmpty(originalSlotOrder)) {
            log.error("原slotOrder不能为空");
            buildBadRequestActionWarn(actionResult, "原slotOrder不能为空");
            return actionResult;
        }
        if (ObjectUtils.isEmpty(newSlotOrder)) {
            log.error("新slotOrder不能为空");
            buildBadRequestActionWarn(actionResult, "新slotOrder不能为空");
            return actionResult;
        }
        try {
            KnwSlot knwSlot = knwSlotMapper.selectByPrimaryKey(slotSoid);

            //拖拽数据更新
            KnwSlot slot = new KnwSlot();
            slot.setSlotSoid(slotSoid);
            slot.setSoltOrder(newSlotOrder);
            knwSlotMapper.updateByPrimaryKeySelective(slot);

            //区分排序
            if (newSlotOrder > originalSlotOrder) {
                //被挤数据排序全部-1
                boolean result = knwSlotMapper.updateSlotOrderLess(originalSlotOrder, newSlotOrder, slotSoid, knwSlot.getNoumenonSoid());
                if (!result) {
                    throw new DtException("拖拽排序出现异常");
                }
            } else {
                //被挤数据排序全部+1
                boolean result = knwSlotMapper.updateSlotOrderPlus(newSlotOrder, originalSlotOrder, slotSoid, knwSlot.getNoumenonSoid());
                if (!result) {
                    throw new DtException("拖拽排序出现异常");
                }
            }
            buildActionSuccess(actionResult);
        } catch (Exception e) {
            log.error("排序出现异常,slotSoid:{}", slotSoid);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            buildActionWarn(actionResult, "拖拽排序失败");
        } finally {
            stopWatch.stop();
            log.info("本次排序耗时:" + stopWatch.getTime() + "ms");
        }
        return actionResult;
    }

    /**
     * 更新slot
     *
     * @param knwSlotVO
     * @return
     */
    @Override
    @Transactional(value = "dtdTxManager", rollbackFor = Exception.class)
    public ListResult<Object> update(KnwSlotVo knwSlotVO) throws DtException {
        log.info("开始更新本体slot" + knwSlotVO.toString());
        StopWatch stopWatch = StopWatch.createStarted();
        ListResult listResult = new ListResult();
        try {
            if (knwSlotVO.getSlotSoid() == null) {
                buildBadRequestListWarn(listResult, "SlotSoid不能为空");
                return listResult;
            }

            if (knwSlotVO.getNoumenonSoid() == null) {
                buildBadRequestListWarn(listResult, "本体soid不能为空");
                return listResult;
            }

            if (StringUtils.isEmpty(knwSlotVO.getSlotName())) {
                buildBadRequestListWarn(listResult, "Slot显示名称不能为空");
                return listResult;
            }

            if (ObjectUtils.isEmpty(knwSlotVO.getDataType())) {
                buildBadRequestListWarn(listResult, "值类型不能为空");
                return listResult;
            }

            if(ObjectUtils.isNotEmpty(knwSlotVO.getReferenceUpperLimit()) && ObjectUtils.isEmpty(knwSlotVO.getReferenceLowerLimit())){
                buildBadRequestListWarn(listResult, "参考值范围不能只填一个值");
                return listResult;
            }

            if(ObjectUtils.isNotEmpty(knwSlotVO.getReferenceLowerLimit()) && ObjectUtils.isEmpty(knwSlotVO.getReferenceUpperLimit())){
                buildBadRequestListWarn(listResult, "参考值范围不能只填一个值");
                return listResult;
            }

            if(ObjectUtils.isNotEmpty(knwSlotVO.getReferenceUpperLimit()) && ObjectUtils.isNotEmpty(knwSlotVO.getReferenceUpperLimit())){
                if (knwSlotVO.getReferenceUpperLimit() < knwSlotVO.getReferenceLowerLimit()){
                    buildBadRequestListWarn(listResult, "参考值上限不能小于参考值下限");
                    return listResult;
                }
            }

            //本体是草稿状态
            int countDraft = knwNoumenonMapper.countDraft(knwSlotVO.getNoumenonSoid());
            if (countDraft > 0) {
                KnwSlot knwSlot = knwSlotMapper.selectByPrimaryKey(knwSlotVO.getSlotSoid());
                KnwSlot knwSlotUpdate = buildUpdateObject(knwSlotVO, knwSlot);
                // 设置本体slot标签
                knwSlot.setLable(FrontendReportRule.TAG_SLOT.getCodeName());
                if(knwSlot.getDataType().longValue() == DataType.NUMBER.getCode()){
                    knwSlot.setLable(FrontendReportRule.TAG_NU.getCodeName());
                }
                if (knwSlot.getDataType().longValue() == DataType.VARCHAT.getCode()){
                    knwSlot.setLable(FrontendReportRule.TAG_STR.getCodeName());
                }
                if(knwSlot.getDerailCodingSystemSoid() != null){
                    knwSlot.setLable(FrontendReportRule.TAG_SELE.getCodeName());
                }
                knwSlotMapper.updateByPrimaryKey(knwSlotUpdate);
                buildListSuccess(listResult);
            } else {
                buildBadRequestListWarn(listResult, "本体为非草稿状态,无法更新");
                return listResult;
            }
        } catch (Exception e) {
            log.error("更新本体slot发送异常", e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            buildListWarn(listResult, "更新本体slot失败");
        } finally {
            stopWatch.stop();
            log.info("本次更新耗时:" + stopWatch.getTime() + "ms");
        }
        return listResult;
    }

    /**
     * Slot简码查询
     *
     * @param vo
     * @return
     */
    @Override
    public ListResult<Object> selectSlotNameByCode(MapperPage vo) {

        log.info("开始Slot简码查询" + vo.getSearch());
        StopWatch st = StopWatch.createStarted();
        ListResult result = new ListResult();
        try {
            //整合成下拉框
            List<PullDownMenuVO> tempList = conceptualDetailMapper.selectSlotNameByCode(vo)
                    .stream()
                    .filter(Objects::nonNull)
                    .map(detail -> new PullDownMenuVO(detail.getConceptualDetailSoid(), detail.getConceptualDetailName(), null))
                    .collect(Collectors.toList());


            buildListSuccess(result, tempList);
        } catch (Exception e) {
            log.error("Slot简码查询异常", e);
            buildListWarn(result, "Slot简码查询失败");
        } finally {
            st.stop();
            log.info("本次匹配耗时:" + st.getTime() + "ms");
        }
        return result;
    }

    /**
     * 选中Slot名称后加载定义域
     *
     * @param vo
     * @return
     */
    @Override
    public ListResult<Object> getDataBySlotName(KnwSlotVo vo) {
        if (ObjectUtils.isEmpty(vo.getConceptualSoid())) {
            log.error("conceptualSoid不能为空");
            throw new RuntimeException("参数不能为空");
        }
        log.info("开始加载定义域" + vo.getConceptualSoid());
        StopWatch st = StopWatch.createStarted();
        ListResult result = new ListResult();
        try {
            //因为传给前段的列表中concetualSoid实为 conceptualDetailSoid 所以重新取一遍
//            KnwConceptualDetail knwConceptualDetail = conceptualDetailMapper.selectDetail(vo.getConceptualSoid());
            StringBuilder builder = new StringBuilder();
//            if (knwConceptualDetail != null) {
                //获取定义域,用逗号拼接
//                List<KnwNoumenon> knwNoumenonList = knwNoumenonMapper.selectNoumenonNameByCSoid(knwConceptualDetail.getConceptualSoid());
                List<KnwNoumenon> knwNoumenonList = knwNoumenonMapper.selectNoumenonNameByCSoid(vo.getConceptualSoid());

                AtomicInteger index = new AtomicInteger();
                knwNoumenonList.forEach(knwNoumenon -> {
                    builder.append(knwNoumenon.getNoumenonShowName());
                    if (index.getAndIncrement() < knwNoumenonList.size() - 1) {
                        builder.append(",");
                    }
                });
//            }

            buildListSuccess(result, builder.toString());
        } catch (Exception e) {
            log.error("加载定义域异常", e);
            buildListWarn(result, "加载定义域失败");
        } finally {
            st.stop();
            log.info("本次匹配耗时:" + st.getTime() + "ms");
        }
        return result;
    }

    @Override
    public ListResult<Object> getDataByDomainId(KnwConceptualDomain domain) {
        if (ObjectUtils.isEmpty(domain.getDomainSoid())) {
            log.error("domainSOid不能为空");
            throw new RuntimeException("参数不能为空");
        }
        log.info("开始编码体系查询" + domain.getDomainSoid());
        StopWatch st = StopWatch.createStarted();
        ListResult result = new ListResult();
//        try {
//            //整合成下拉框
//            List<PullDownMenuVO> tempList = detailCodingSystemMapper.selectDetailCodeByDomainId(domain.getDomainSoid())
//                    .stream()
//                    .filter(Objects::nonNull)
//                    .map(detail -> new PullDownMenuVO(detail.getDerailCodingSystemSoid(), detail.getCnName(), null))
//                    .collect(Collectors.toList());
//            buildListSuccess(result, tempList);
//        } catch (Exception e) {
//            log.error("Slot简码查询异常", e);
//            buildListWarn(result, "Slot简码查询失败");
//        } finally {
//            st.stop();
//            log.info("本次匹配耗时:" + st.getTime() + "ms");
//        }
        return result;
    }

    /**
     * 根据本体soid查询所有本体Slot
     *
     * @param noumenonSoid
     * @return
     */
    @Override
    public ListResult<List<KnwSlotVo>> findAllSoltBynoumenonSoid(Long noumenonSoid) {
        log.info("开始查询所有本体Slot" + noumenonSoid);
        StopWatch stopWatch = StopWatch.createStarted();
        ListResult listResult = new ListResult();

        if (ObjectUtils.isEmpty(noumenonSoid)) {
            log.error("本体soid不能为空");
            buildBadRequestListWarn(listResult, "本体soid不能为空");
            return listResult;
        }
        List<KnwSlotVo> list = null;
        try {
            list = knwSlotMapper.selectAllSlotVoByNoumenonSoid(noumenonSoid);
            buildListSuccess(listResult, list);
        } catch (Exception e) {
            log.error("查询所有本体Slot异常", e);
            buildListWarn(listResult, "查询所有本体Slot失败");
        } finally {
            stopWatch.stop();
            log.info("本次查询耗时:" + stopWatch.getTime() + "ms");
        }
        return listResult;
    }

    public KnwSlot buildUpdateObject(KnwSlotVo knwSlotVo, KnwSlot knwSlot) {
        knwSlot.setBasic(knwSlotVo.getBasic());
        knwSlot.setConceptualSoid(knwSlotVo.getConceptualSoid());
        knwSlot.setDataType(knwSlotVo.getDataType());
        knwSlot.setDefaultNumber(knwSlotVo.getDefaultNumber());
        knwSlot.setDerailCodingSystemSoid(knwSlotVo.getDerailCodingSystemSoid());
        knwSlot.setMaxNumber(knwSlotVo.getMaxNumber());
        knwSlot.setMinNumber(knwSlotVo.getMinNumber());
        knwSlot.setNoumenonSoid(knwSlotVo.getNoumenonSoid());
        knwSlot.setPyCode(knwSlotVo.getPyCode());
        knwSlot.setWbCode(knwSlotVo.getWbCode());
        knwSlot.setSlotName(knwSlotVo.getSlotName());
        knwSlot.setUnit(knwSlotVo.getUnit());
        knwSlot.setUpdateDate(new Date());
        knwSlot.setLable(knwSlotVo.getLable());
        knwSlot.setReferenceUpperLimit(knwSlotVo.getReferenceUpperLimit());
        knwSlot.setReferenceLowerLimit(knwSlotVo.getReferenceLowerLimit());
        knwSlot.setReferenceQualitativeMaintenance(knwSlotVo.getReferenceQualitativeMaintenance());
        return knwSlot;
    }
}
